package com.h2cloud.aspect.cacheAble;

import com.h2cloud.aspect.BaseAspect;
import com.h2cloud.depends.cache.CacheService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/***
 * 缓存拦截器
 */
//@Order(5)
//@Aspect
//@Component
public class CacheAspect extends BaseAspect {

    private final static Logger logger = LoggerFactory.getLogger(CacheAspect.class);

    @Autowired
    private CacheService cacheService;

    /**
     * 后期改成配置
     */
    private static boolean isCacheEnabled = true;

    @Pointcut("@annotation(com.h2cloud.aspect.cacheAble.Cacheable)")
    public void methodPointCut() {

    }

    /**
     *
     */
    @Around("methodPointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        Cacheable cacheable = getAnnotation(joinPoint, Cacheable.class);
        //开启缓存
        if (cacheable != null && isCacheEnabled) {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = getArgStr(joinPoint.getArgs(), cacheable.paramName(), joinPoint.getSignature());
            int expire = cacheable.expire();

            String key = getCacheKey(cacheable.key(), targetName, methodName, arguments);
            logger.debug("aop start,,cacheKey:{}", key);
            Object result = cacheService.get(key, cacheable);

            if (result != null) {
                //如果缓存命中直接返回缓存中的结果
                return result;
            } else {
                result = joinPoint.proceed();
                if (result != null) {
                    cacheService.set(key, result, cacheable);
                    logger.info("aop end,get result from DB,,cacheKey={},,cacheExpire={}", key, expire);
                }
            }
            return result;
        } else {
            logger.info("aop end,get result from DB,,cache.enabled=false");
            return joinPoint.proceed();
        }
    }
}
